/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package MyClass;

import java.util.Random;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.game.Sprite;

/**
 *
 * @author HuuTai_it
 */
public class GameManagement extends GameCanvas implements Runnable {  
    
    public Control control;    
    private boolean moving ;
    public Random r = new Random();
    public LayerManager layerManager = new LayerManager();
    public int[][] element = new int[10][10];
    
    private Image backgroundImage = Image.createImage("/MyPicture/background.png");   
    private Background background = new Background(backgroundImage); 
    
    public Image cannonImage = Image.createImage("/MyPicture/cannon.png");  
    public Image rubbleImage = Image.createImage("/MyPicture/rubble.png"); 
    
    private Image diffImage = Image.createImage("/MyPicture/difficult.png");   
    private Difficulties difficulties = new Difficulties(diffImage);    
    
    private Image numberImage = Image.createImage("/MyPicture/number.png");   
    private Information information = new Information(numberImage);
    
    private Image vortexImage = Image.createImage("/MyPicture/vortex.png");   
    private Vortexs vortexs;
    
    private Image islandImage = Image.createImage("/MyPicture/island.png");   
    private Islands islands;
    
    private Image mainShipImage = Image.createImage("/MyPicture/mainship.png");   
    public MainShip mainShip;
    private EnemyManagement enemyManagement;
    private int x;
    private int y;
    public boolean burning;
    public boolean play = true;
    public int bsc = 1;
    public boolean lvuping = false;
    public Sprite Slvup;
    public boolean eneFiring = false;
    public GameManagement(Control control) throws Exception {
        
        super(true); 
        moving = false;
        burning = false;
        this.control = control;
        setFullScreenMode(true);  
        
        createLevel();
    }
    
    public void createLevel() throws Exception {
        
        layerManager = new LayerManager();
        for(int i = 0; i < 10; i++)
            for(int j = 0; j < 10; j++)
                element[i][j] = 0; 
        
        Slvup = new Sprite(Image.createImage("/MyPicture/lvup.png"), 160, 120);
        Slvup.setPosition(40, 100);
        this.layerManager.append(Slvup);
        Slvup.setVisible(false);
        vortexs = new Vortexs(this, vortexImage);
        
        mainShip = new MainShip(this, mainShipImage);
        layerManager.append(mainShip);
        layerManager.append(mainShip.a);
        layerManager.append(mainShip.b);
        layerManager.append(mainShip.r);
        
        enemyManagement = new EnemyManagement(this);
        if(enemyManagement.mons != null)
            layerManager.append(enemyManagement.mons );
            
        int n = enemyManagement.vEnemy.size();
        for(int i = 0; i < n; i++)
        {
            layerManager.append((Sprite)enemyManagement.vEnemy.elementAt(i));
            layerManager.append(((Ship)enemyManagement.vEnemy.elementAt(i)).a);
            layerManager.append(((Ship)enemyManagement.vEnemy.elementAt(i)).b);
            layerManager.append(((Ship)enemyManagement.vEnemy.elementAt(i)).r);
        }
                
        for(int i = 0; i < vortexs.vVortex.size(); i++)
            layerManager.append((Sprite)vortexs.vVortex.elementAt(i));
        
        islands = new Islands(this, islandImage);
        
        layerManager.append(islands);        
        
        difficulties.setDiff(control.difficulties);
        layerManager.append(difficulties);
        information.setLevel(control.level);
        information.setScores(control.scores);
        information.setLife(control.life);
        layerManager.append(information);
        layerManager.append(background);
        
    }
    
    public void start() {        
        
        Thread t = new Thread(this);
        t.start();
    }
    
    public void run() {
        try
        {
        int count = 0;
        Graphics g = getGraphics();
        while(play){
            if(control.scores > bsc * 500)
            {
                control.life++;
                bsc++;
                control.bonusship();
            }
            information.setScores(control.scores);
            information.setLife(control.life);
            information.setLevel(control.level);
            boolean move = false;
            //=================xet lv up
            boolean lvup = true;
            for(int i = 0; i < enemyManagement.vEnemy.size(); i++)
            {
                if(!((Ship)enemyManagement.vEnemy.elementAt(i)).die)
                    lvup = false;
            }
            if(lvup && !lvuping)
            {
                if(control.level < 15)
                {
                    control.level++;
                    lvuping = true;
                    Slvup.setVisible(true);
                }
                else {play = false;control.showGameWinScreen();}
            }
            //===============xet enemy bi trung dan
            if(mainShip.firing)
            {
                
                for(int i = 0; i < enemyManagement.vEnemy.size(); i++)
                {
                    boolean isfired = false;
                    if(((Ship)enemyManagement.vEnemy.elementAt(i)).collidesWith(mainShip.a, true)
                            && !((Ship)enemyManagement.vEnemy.elementAt(i)).die)
                    {
                        mainShip.a.stopFire();
                        isfired = true;
                    }
                    else
                    if(((Ship)enemyManagement.vEnemy.elementAt(i)).collidesWith(mainShip.b, true)
                            && !((Ship)enemyManagement.vEnemy.elementAt(i)).die)
                    {
                        mainShip.b.stopFire();
                        isfired = true;
                    }
                    if(isfired == true)
                    {
                        burning = true;
                        move = true;
                        control.scores += ((Ship)enemyManagement.vEnemy.elementAt(i)).sType*10;                        
                        element[((Ship)enemyManagement.vEnemy.elementAt(i)).getX()/24]
                                [((Ship)enemyManagement.vEnemy.elementAt(i)).getY()/24] = 9;
                        
                            control.explode();
                        ((Ship)enemyManagement.vEnemy.elementAt(i)).setFrameSequence
                                (((Ship)enemyManagement.vEnemy.elementAt(i)).explode);
                        
                        ((Ship)enemyManagement.vEnemy.elementAt(i)).die = true;
                        
                      ((Ship)enemyManagement.vEnemy.elementAt(i)).r.setPosition(
                              ((Ship)enemyManagement.vEnemy.elementAt(i)).getX(),
                              ((Ship)enemyManagement.vEnemy.elementAt(i)).getY());
                      
                      ((Ship)enemyManagement.vEnemy.elementAt(i)).r.setVisible(true);     
                    }
                }
            }
            //=========== thay doi vortex
            if(count == 3)
            {
                count = 0;
                if(control.difficulties == 3)
                    vortexs.appearManager();
            }
            //=========xet thuyen vao vortex
            if(mainShip.inV && mainShip.getFrame() == 30)
            {
                do
                {
                     x = Math.abs(r.nextInt() % 10);
                     y = Math.abs(r.nextInt() % 10);
                }
                while(element[x][y] != 0 );
                switch(mainShip.direction) {
            
                case 1:mainShip.setFrameSequence(mainShip.frameUp);break;
                case 2:mainShip.setFrameSequence(mainShip.frameUpRight);break;
                case 3:mainShip.setFrameSequence(mainShip.frameRight);break;
                case 4:mainShip.setFrameSequence(mainShip.frameDownRight);break;
                case 5:mainShip.setFrameSequence(mainShip.frameDown);break;
                case 6:mainShip.setFrameSequence(mainShip.frameDownLeft);break;
                case 7:mainShip.setFrameSequence(mainShip.frameLeft);break;
                case 8:mainShip.setFrameSequence(mainShip.frameUpLeft);break;
                }
                mainShip.setPosition(x*24, y*24);
                mainShip.inV = false;
                element[x][y] = 3;
                int a = 0;
                for(int i = 0; i < enemyManagement.vEnemy.size(); i++)
                {
                    
                    if(enemyManagement.mons!= null && i == 0)enemyManagement.mons.autoMove(mainShip);
                    if(!((Ship)enemyManagement.vEnemy.elementAt(i)).die )
                    {
                        a++;
                        ((Ship)enemyManagement.vEnemy.elementAt(i)).autoMove(mainShip);
                    }
                }
                if (a >0 ) control.move();
            }
            else
            if((mainShip.moves() == 1 || mainShip.fire() == 1 ||( !burning && move)  ))
            {   
                count ++;
                if(element[mainShip.getX()/24][mainShip.getY()/24] == 1)
                {
                    mainShip.inV = true;
                    mainShip.setFrameSequence(mainShip.inVortex);                   

                }
                else
                for(int i = 0; i < enemyManagement.vEnemy.size(); i++)
                {
                    if( i  == 0 && !((Ship)enemyManagement.vEnemy.elementAt(i)).die)
                        control.move();
                    if(i == 0 && enemyManagement.mons!= null )
                        enemyManagement.mons.autoMove(mainShip);
                    if(!((Ship)enemyManagement.vEnemy.elementAt(i)).die )
                        ((Ship)enemyManagement.vEnemy.elementAt(i)).autoMove(mainShip);
                }
            }
            
            //===============move lien tuc de cac thuyen di chuyen
            int a = 0;
            if( enemyManagement.mons!= null && enemyManagement.mons.count > 0)
                       enemyManagement.mons.autoMove(mainShip);
            for(int i = 0; i < enemyManagement.vEnemy.size(); i++)
               if(((Ship)enemyManagement.vEnemy.elementAt(i)).count > 0  && 
                       !((Ship)enemyManagement.vEnemy.elementAt(i)).die)
               { 
                   a++;
                   ((Ship)enemyManagement.vEnemy.elementAt(i)).autoMove(mainShip);
                        
               }
            //============= xet cac thuyen di chuyen xong chua
            if( a == enemyManagement.vEnemy.size() )
                moving = true;
            else
            {
                moving = false;
            }
            //===================ban
            
            if(eneFiring && !moving)
            {
                int u = 0, n = 0;
                for(int i = 0; i < enemyManagement.vEnemy.size(); i++)
                   if(!((Ship)enemyManagement.vEnemy.elementAt(i)).die 
                           &&((Ship)enemyManagement.vEnemy.elementAt(i)).sType == 4 && 
                           ((Ship)enemyManagement.vEnemy.elementAt(i)).firing)
                   {
                        n++;
                        if(((Ship)enemyManagement.vEnemy.elementAt(i)).fire() == 1)
                            u++;
                        //============ xet ban trung main
                        boolean isfireda = false;
                            if(mainShip.collidesWith(
                                    ((Ship)enemyManagement.vEnemy.elementAt(i)).a, true))
                            {
                                ((Ship)enemyManagement.vEnemy.elementAt(i)).a.stopFire();
                                isfireda = true;
                            }
                            else
                            if(mainShip.collidesWith(
                                    ((Ship)enemyManagement.vEnemy.elementAt(i)).b, true))
                            {
                                ((Ship)enemyManagement.vEnemy.elementAt(i)).b.stopFire();
                                isfireda = true;
                            }
                        if(isfireda == true)
                        {
                            burning = true;
                            move = true;
                            element[mainShip.getX()/24][mainShip.getY()/24] = 9;
                            control.explode();
                            mainShip.setFrameSequence(mainShip.explode);
                            mainShip.r.setPosition(mainShip.getX(), mainShip.getY());
                            mainShip.r.setVisible(true);  
                        }
                        //============ xet enemy ban trung enemy
                        for(int j = 0; j < enemyManagement.vEnemy.size(); j++)
                        {
                            boolean isfireds = false;
                            if(((Ship)enemyManagement.vEnemy.elementAt(j)).collidesWith(
                                    ((Ship)enemyManagement.vEnemy.elementAt(i)).a, true)
                                    &&((Ship)enemyManagement.vEnemy.elementAt(j)).getX() % 24 == 0
                                    &&((Ship)enemyManagement.vEnemy.elementAt(j)).getY() % 24 == 0
                                    && !((Ship)enemyManagement.vEnemy.elementAt(j)).die)
                            {
                                ((Ship)enemyManagement.vEnemy.elementAt(i)).a.stopFire();
                                isfireds = true;
                            }
                            else
                            if(((Ship)enemyManagement.vEnemy.elementAt(j)).collidesWith(
                                    ((Ship)enemyManagement.vEnemy.elementAt(i)).b, true)
                                    && !((Ship)enemyManagement.vEnemy.elementAt(j)).die)
                            {
                                ((Ship)enemyManagement.vEnemy.elementAt(i)).b.stopFire();
                                isfireds = true;
                            }
                            if(isfireds == true)
                            {
                                burning = true;
                                move = true;
                                element[((Ship)enemyManagement.vEnemy.elementAt(j)).getX()/24]
                                        [((Ship)enemyManagement.vEnemy.elementAt(j)).getY()/24] = 9;

                                    control.explode();
                                ((Ship)enemyManagement.vEnemy.elementAt(j)).setFrameSequence
                                        (((Ship)enemyManagement.vEnemy.elementAt(j)).explode);

                                ((Ship)enemyManagement.vEnemy.elementAt(j)).die = true;

                              ((Ship)enemyManagement.vEnemy.elementAt(j)).r.setPosition(
                                      ((Ship)enemyManagement.vEnemy.elementAt(j)).getX(),
                                      ((Ship)enemyManagement.vEnemy.elementAt(j)).getY());

                              ((Ship)enemyManagement.vEnemy.elementAt(j)).r.setVisible(true);     
                            }
                        }
                   }
                
                if(u == n) eneFiring = false;
            }
            //============= xet khi thuyen di chuyen xong
            if(!moving && !eneFiring)
            {
                //================ main ship bi. va cha.m
                for(int i = 0; i < enemyManagement.vEnemy.size(); i++)
                {
                    int ex = ((Ship)enemyManagement.vEnemy.elementAt(i)).getX();
                    int ey = ((Ship)enemyManagement.vEnemy.elementAt(i)).getY();
                    if(ex % 24 == 0 && ey % 24 == 0 &&
                            element[ex/24][ey/24] == 3 
                            && !((Ship)enemyManagement.vEnemy.elementAt(i)).die)
                    {
                        element[ex/24][ey/24] = 9;
                        control.scores += ((Ship)enemyManagement.vEnemy.elementAt(i)).sType*10;
                      ((Ship)enemyManagement.vEnemy.elementAt(i)).r.setPosition(
                              ((Ship)enemyManagement.vEnemy.elementAt(i)).getX(),
                              ((Ship)enemyManagement.vEnemy.elementAt(i)).getY());
                      
                      ((Ship)enemyManagement.vEnemy.elementAt(i)).r.setVisible(true);    
                      
                        ((Ship)enemyManagement.vEnemy.elementAt(i)).die = true;
                            control.explode();
                         
                        ((Ship)enemyManagement.vEnemy.elementAt(i)).setFrameSequence
                            (((Ship)enemyManagement.vEnemy.elementAt(i)).explode);

                        burning = true;
                        move = true;
                        if(control.life > 0)
                        {
                            control.life --;
                            do
                            {
                                 x = Math.abs(r.nextInt() % 10);
                                 y = Math.abs(r.nextInt() % 10);
                            }
                            while(element[x][y] != 0 );
                            switch(mainShip.direction) {

                            case 1:mainShip.setFrameSequence(mainShip.frameUp);break;
                            case 2:mainShip.setFrameSequence(mainShip.frameUpRight);break;
                            case 3:mainShip.setFrameSequence(mainShip.frameRight);break;
                            case 4:mainShip.setFrameSequence(mainShip.frameDownRight);break;
                            case 5:mainShip.setFrameSequence(mainShip.frameDown);break;
                            case 6:mainShip.setFrameSequence(mainShip.frameDownLeft);break;
                            case 7:mainShip.setFrameSequence(mainShip.frameLeft);break;
                            case 8:mainShip.setFrameSequence(mainShip.frameUpLeft);break;
                            }
                            mainShip.setPosition(x*24, y*24);
                            element[x][y] = 3;
                        }
                        else {play = false ; control.showGameOverScreen();}
                    }
                }
                //==========enemy va cham dao, rubble
                for(int i = 0; i < enemyManagement.vEnemy.size(); i++)
                {
                    int ex = ((Ship)enemyManagement.vEnemy.elementAt(i)).getX();
                    int ey = ((Ship)enemyManagement.vEnemy.elementAt(i)).getY();
                    if(ex % 24 == 0 && ey % 24 == 0 &&
                            (element[ex/24][ey/24] == 2 || element[ex/24][ey/24] == 9) 
                            && !((Ship)enemyManagement.vEnemy.elementAt(i)).die)
                    {
                        control.scores += ((Ship)enemyManagement.vEnemy.elementAt(i)).sType*10 + 10;

                         ((Ship)enemyManagement.vEnemy.elementAt(i)).setFrameSequence
                                (((Ship)enemyManagement.vEnemy.elementAt(i)).explode);
                         control.explode();
                        ((Ship)enemyManagement.vEnemy.elementAt(i)).die = true;
                        
                            burning = true;
                            move = true;
                    }
                }
                //======== enemy bi monster an
                for(int i = 0; i < enemyManagement.vEnemy.size(); i++)
                    if(enemyManagement.mons != null &&
                            ((Ship)enemyManagement.vEnemy.elementAt(i)).collidesWith(enemyManagement.mons, false)
                            && !((Ship)enemyManagement.vEnemy.elementAt(i)).die)
                    {
                            control.monster();
                         
                        ((Ship)enemyManagement.vEnemy.elementAt(i)).die = true;
                        ((Ship)enemyManagement.vEnemy.elementAt(i)).setVisible(false);
                            move = true;
                    }
                //============= enemy va cham nhau
                for(int i = 0; i < enemyManagement.vEnemy.size() - 1; i++)
                    for(int j = i + 1; j < enemyManagement.vEnemy.size(); j++)
                    {
                        int ex1 = ((Ship)enemyManagement.vEnemy.elementAt(i)).getX();
                        int ey1 = ((Ship)enemyManagement.vEnemy.elementAt(i)).getY();
                        int ex2 = ((Ship)enemyManagement.vEnemy.elementAt(j)).getX();
                        int ey2 = ((Ship)enemyManagement.vEnemy.elementAt(j)).getY();
                        if(ex1 % 24 == 0 && ey1 % 24 == 0 && ex2 % 24 == 0 && ey2 % 24 == 0 &&
                                ex1 == ex2 && ey1 == ey2 &&
                                ((Ship)enemyManagement.vEnemy.elementAt(i)).collidesWith(
                                ((Ship)enemyManagement.vEnemy.elementAt(j)), false)
                                && element[ex1/24][ey1/24] != 2 
                                && !((Ship)enemyManagement.vEnemy.elementAt(i)).die
                                && !((Ship)enemyManagement.vEnemy.elementAt(j)).die)
                        {
                            control.scores += (((Ship)enemyManagement.vEnemy.elementAt(i)).sType 
                                    +((Ship)enemyManagement.vEnemy.elementAt(j)).sType)* 10 + 20;                           
                            element[ex1/24][ey1/24] = 9;
                            control.explode();
                            ((Ship)enemyManagement.vEnemy.elementAt(i)).setFrameSequence
                                (((Ship)enemyManagement.vEnemy.elementAt(i)).explode);
                            
                            ((Ship)enemyManagement.vEnemy.elementAt(i)).die = true;
                            ((Ship)enemyManagement.vEnemy.elementAt(j)).die = true;
                            
                            layerManager.remove((Ship)enemyManagement.vEnemy.elementAt(j));
                            burning = true;
                            move = true;
                            
                            ((Ship)enemyManagement.vEnemy.elementAt(i)).r.setPosition(ex1,ey1);
                            
                            ((Ship)enemyManagement.vEnemy.elementAt(i)).r.setVisible(true);
                            //enemyManagement.vEnemy.removeElementAt(i);
                        }
                    }
            }
            drawScreen(g);
            
            
            try {
                Thread.sleep(20);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
              System.out.println(ex);
            }
        }
        }
        catch(ArrayIndexOutOfBoundsException ex){
            ex.printStackTrace();
              System.out.println(ex);
        }
             
            
    }
    
    public void drawScreen(Graphics g) {
        
        long currTime = System.currentTimeMillis();
        vortexs.turn(currTime);
        mainShip.wobble(currTime);
        if(mainShip.getFrameSequenceLength() == 16 && mainShip.getFrame() == 14)
        {
            try
            {
                mainShip = new MainShip(this,this.mainShipImage);
                layerManager.insert(mainShip, 0);
                layerManager.insert(mainShip.a, 0);
                layerManager.insert(mainShip.b, 0);
                layerManager.insert(mainShip.r, 0);
                
                if(control.life > 0)
                    {
                        control.life --;
                        do
                        {
                             x = Math.abs(r.nextInt() % 10);
                             y = Math.abs(r.nextInt() % 10);
                        }
                        while(element[x][y] != 0 );
                        switch(mainShip.direction) {

                        case 1:mainShip.setFrameSequence(mainShip.frameUp);break;
                        case 2:mainShip.setFrameSequence(mainShip.frameUpRight);break;
                        case 3:mainShip.setFrameSequence(mainShip.frameRight);break;
                        case 4:mainShip.setFrameSequence(mainShip.frameDownRight);break;
                        case 5:mainShip.setFrameSequence(mainShip.frameDown);break;
                        case 6:mainShip.setFrameSequence(mainShip.frameDownLeft);break;
                        case 7:mainShip.setFrameSequence(mainShip.frameLeft);break;
                        case 8:mainShip.setFrameSequence(mainShip.frameUpLeft);break;
                        }
                        mainShip.setPosition(x*24, y*24);
                        element[x][y] = 3;
                    }
                    else {play = false;control.showGameOverScreen();}
            }
            catch(Exception ex)
            {
                ex.printStackTrace();
                System.out.println(ex);
            }
        }
        enemyManagement.wobble(currTime);
        
        layerManager.paint(g, 0, 0);
        flushGraphics();
    }
    public int getGameAction(int keyCode)
    {
        if(!mainShip.startMove && !mainShip.firing && !moving && !eneFiring)   
        switch(keyCode)
        {
            case KEY_NUM1:if(!lvuping)
                mainShip.moveUpLeft(3);
                break;
            case KEY_NUM2:if(!lvuping)
                mainShip.moveUp(3);
                break;
            case KEY_NUM3:if(!lvuping)                 
                mainShip.moveUpRight(3);
                break;
            case KEY_NUM4:if(!lvuping)                  
                mainShip.moveLeft(3);
                break;
            case KEY_NUM5:if(!lvuping)
            {
                int d = 0;
                if( mainShip.direction == 4 ||  mainShip.direction == 8) d = 2;
                else if( mainShip.direction == 1 ||  mainShip.direction == 5) d = 3;
                else if( mainShip.direction == 7 ||  mainShip.direction == 3) d = 1;
                else if( mainShip.direction == 2 ||  mainShip.direction == 6) d = 4;
                mainShip.firing = true;
                if(mainShip.a.setD(d) + mainShip.b.setD(d+4) == 0) 
                    mainShip.firing = false;
                else control.shoot();
            }
                break;
            case KEY_NUM6:if(!lvuping)                
                mainShip.moveRight(3);
                break;
            case KEY_NUM7:if(!lvuping)                
                mainShip.moveDownLeft(3);
                break;            
            case KEY_NUM8:if(!lvuping)            
                mainShip.moveDown(3);
                break;
            case KEY_NUM9:if(!lvuping)                
                mainShip.moveDownRight(3);
                break;
            case KEY_NUM0:
                try
                    {
                        this.createLevel();
                    }
                    catch(Exception ex)
                    {
                        ex.printStackTrace();
                        System.out.println(ex);
                    }
                lvuping = false;
                break;
            case KEY_POUND:             
                
                play = false;
                HighScoresSave hss = new HighScoresSave();
                GameSave gs = new GameSave(control);
                try {
                    hss.updateHighScores(control.scores);
                    gs.SaveGame();
                }
                catch(Exception ex){}
                control.level = 1;
                control.scores = 0;
                control.life = 4 - control.difficulties;
                control.showMainMenu();
                break;
            case KEY_STAR:
                
                if(control.activeSound)
                    control.activeSound = false;
                else
                    control.activeSound = true;
                break;
        }
        return 0;
    }  
}
